package cn.tedu.service.impl;

import cn.tedu.constant.WxConstant;
import cn.tedu.constant.WxUrlConstant;
import cn.tedu.service.IWx2311Service;
import cn.tedu.util.HttpClientUtil;
import cn.tedu.vo.AccessTokenBean;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.util.crypto.SHA1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class Wx2311ServiceImpl implements IWx2311Service {

    @Value("${wx.token}")
    private String token;

    @Value("${wx.appID}")
    private String appId;

    @Value("${wx.appsecret}")
    private String secret;


    @Value("${wx.baseUrl}")
    private String baseUrl;

    // 懒汉单例   贫血模型 充血模型
    private AccessTokenBean accessTokenBean ;



    @Override
    public String createMenu() {

        String redirectUrl = WxUrlConstant.OAUTH2_AUTHORIZE.replace("APPID", appId)
                .replace("REDIRECT_URI", baseUrl + "/wx2311/getCode")
                .replace("SCOPE", "snsapi_userinfo");;

        // 准备菜单对象
        WxMenu wxMenu = new WxMenu();
        // 一级按钮们
        List<WxMenuButton> firstButtons = new ArrayList<>();
        // 二级按钮们
        List<WxMenuButton> subButtons = new ArrayList<>();
        // 准备一级按钮
        // 点击去百度
        WxMenuButton firstOne = new WxMenuButton();
        firstOne.setType(WxConsts.MenuButtonType.CLICK);
        firstOne.setName("了解更多");
        firstOne.setKey(WxConstant.CLICK_KEY);
        // 点击调用照相机
        WxMenuButton firstTwo = new WxMenuButton();
        firstTwo.setType(WxConsts.MenuButtonType.PIC_PHOTO_OR_ALBUM);
        firstTwo.setName("拍照/照片");
        firstTwo.setKey(WxConstant.PIC_PHOTO_OR_ALBUM_KEY);
        // 准备第一个一级按钮的二级按钮
        // 地理位置
        WxMenuButton oneSubOne = new WxMenuButton();
        oneSubOne.setName("发送定位");
        oneSubOne.setType(WxConsts.MenuButtonType.LOCATION_SELECT);
        oneSubOne.setKey(WxConstant.LOCATION_SELECT_KEY);
        WxMenuButton oneSubTwo = new WxMenuButton();
        oneSubTwo.setName("生鲜");
        oneSubTwo.setType(WxConsts.MenuButtonType.VIEW);
        oneSubTwo.setUrl(redirectUrl);

        // 第一级的第一个按钮 设置子按钮
        subButtons.add(oneSubOne);
        subButtons.add(oneSubTwo);
        firstOne.setSubButtons(subButtons);
        // 添加一级按钮
        firstButtons.add(firstOne);
        firstButtons.add(firstTwo);
        // 为菜单设置一级按钮
        wxMenu.setButtons(firstButtons);
        String url =  WxUrlConstant.CREATE_MENU.replace(WxConstant.DX_ACCESS_TOKEN,getAccessToken());
        // 发请求给微信创建菜单

        return HttpClientUtil.doPostJson(url, wxMenu.toJson());

    }




    @Override
    public String getAccessToken() {

        // 解决并发安全问题  100  99000
        if(accessTokenBean==null||accessTokenBean.isExpired()){
            // 99
            synchronized (this){
                // 1
                if(accessTokenBean==null||accessTokenBean.isExpired()){
                    // 43ms 1
                    refreshToken();
                }
            }
        }

        return accessTokenBean.getAccessToken();
    }


    /**
     * 该方法需要请求到wx服务器，拿到token ，2小时调用一次
     */
    public void refreshToken(){
        // 准备url，替换appid和secret
        String url = WxUrlConstant.ACCESS_TOKEN.replace(WxConstant.APPID,appId).replace(WxConstant.SECRET,secret);
        // 发请求给wx，得到token
        String s = HttpClientUtil.doGet(url);
        // 保存accessToken
        JSONObject jsonObject = JSON.parseObject(s);
        String accessToken =(String) jsonObject.get(WxConstant.ACCESS_TOKEN);
        Long expiresIn = Long.parseLong((Integer)jsonObject.get(WxConstant.EXPIRES_IN)+"");
        accessTokenBean = new AccessTokenBean(appId, secret, accessToken, expiresIn);
    }

    @Override
    public boolean checkWx(String signature, String timestamp, String nonce, String echostr) {
        //1）将token、timestamp、nonce三个参数进行字典序排序
        String[] strs = new String[]{token,timestamp,nonce};
        Arrays.sort(strs);
        //2）将三个参数字符串拼接成一个字符串进行sha1加密
        StringBuilder stringBuilder = new StringBuilder();
        for (String str : strs) {
            stringBuilder.append(str);
        }
        String sha1Signature = SHA1.gen(stringBuilder.toString());

        //3）开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
        return sha1Signature.equals(signature);
    }

}
